package com.cw.lang.common.framework.config;

import javax.validation.Validator;

import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;

import com.cw.lang.common.framework.aspect.ControllerBizParameterValidatorAspect;
import com.cw.lang.common.framework.feign.RequestHeaderInterceptor;
import com.cw.lang.common.framework.feign.RpcExceptionFeignInterceptor;
import com.cw.lang.common.framework.feign.RpcLoggingFeignInterceptor;
import com.cw.lang.common.framework.handle.DubboGenericServiceHandle;
import com.cw.lang.common.framework.inteceptor.CommonResponseMvcHandlerInterceptor;
import com.cw.lang.common.framework.inteceptor.ControllerFlagMvcHandlerInterceptor;
import com.cw.lang.common.framework.inteceptor.IdempotentMvcHandlerInterceptor;
import com.cw.lang.common.framework.inteceptor.RequestHeaderMvcHandlerInterceptor;
import com.cw.lang.common.framework.inteceptor.RequestValidatorMvcHandlerInterceptor;
import com.cw.lang.common.framework.okhttp.LocalInterceptor;
import com.cw.lang.common.framework.rpc.ExceptionCatchIntegrationHandlerAspect;
import com.cw.lang.common.framework.rpc.RequestIntegrationHandlerAspect;
import com.cw.lang.common.framework.rpc.RpcExceptionConfigHandlerAspect;
import com.fasterxml.jackson.databind.ObjectMapper;

import feign.RequestInterceptor;

/**
 * @author chenw
 * @version V2.1
 * @since 2.1.0 2019-03-11 09:44
 */
@Configuration
public class FrameworkRpcConfiguration {

    @Configuration
    public static class FrameworkRpcAspectConfiguration {

        @Bean
        public ControllerBizParameterValidatorAspect controllerBizParameterValidatorAspect(Validator validator) {
            ControllerBizParameterValidatorAspect aspect = new ControllerBizParameterValidatorAspect();
            aspect.setValidator(validator);
            return aspect;
        }

        @Bean
        public ExceptionCatchIntegrationHandlerAspect exceptionCatchIntegrationHandlerAspect() {
            return new ExceptionCatchIntegrationHandlerAspect();
        }

        @Bean
        public RequestIntegrationHandlerAspect baseRequestIntegrationHandlerAspect() {
            return new RequestIntegrationHandlerAspect();
        }

        @Bean
        public RpcExceptionConfigHandlerAspect rpcExceptionConfigHandlerAspect() {
            return new RpcExceptionConfigHandlerAspect();
        }
    }

    @Configuration
    @EnableConfigurationProperties(FrameworkRpcProperties.class)
    public static class FrameworkRpcFeignConfiguration {

        @Bean
        public LocalInterceptor rpcLoggingFeignInterceptor() {
            return new RpcLoggingFeignInterceptor();
        }
        @Bean
        public RequestInterceptor requestInterceptor() {
            return new RequestHeaderInterceptor();
        }

        @Bean
        public LocalInterceptor rpcExceptionFeignInterceptor(ObjectMapper objectMapper,
            FrameworkRpcProperties properties) {
            RpcExceptionFeignInterceptor interceptor = new RpcExceptionFeignInterceptor();
            interceptor.setObjectMapper(objectMapper);
            interceptor.setRpcProperties(properties.getRpc());
            return interceptor;
        }
        @Bean
        public DubboGenericServiceHandle dubboGenericServiceHandle(){
            return new DubboGenericServiceHandle();
        }
    }

    @Configuration
    @EnableConfigurationProperties(FrameworkRpcProperties.class)
    public static class FrameworkRpcMvcConfiguration {
        @Bean
        public HandlerInterceptor controllerFlagMvcHandlerInterceptor() {
            return new ControllerFlagMvcHandlerInterceptor();
        }
        // @Bean
        // public HandlerInterceptor inOutLoggingMvcHandlerInterceptor() {
        //     return new InOutLoggingMvcHandlerInterceptor();
        // }
        @Bean
        public HandlerInterceptor commonResponseMvcHandlerInterceptor() {
            return new CommonResponseMvcHandlerInterceptor();
        }

        @Bean
        public HandlerInterceptor baseRequestHeaderMvcHandlerInterceptor() {
            return new RequestHeaderMvcHandlerInterceptor();
        }

        @Bean
        public HandlerInterceptor baseRequestValidatorMvcHandlerInterceptor(Validator validator) {
            RequestValidatorMvcHandlerInterceptor interceptor = new RequestValidatorMvcHandlerInterceptor();
            interceptor.setValidator(validator);
            return interceptor;
        }

        @Bean
        public HandlerInterceptor idempotentMvcHandlerInterceptor(FrameworkRpcProperties frameworkRpcProperties) {
            IdempotentMvcHandlerInterceptor interceptor = new IdempotentMvcHandlerInterceptor();
            interceptor.setFrameworkRpcProperties(frameworkRpcProperties);
            return interceptor;
        }
    }
}
